home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / OpenGL / fadeflip / fadeflip.c++ next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  10.3 KB  |  411 lines

  1. /*
  2.  * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED
  4.  * Permission to use, copy, modify, and distribute this software for
  5.  * any purpose and without fee is hereby granted, provided that the above
  6.  * copyright notice appear in all copies and that both the copyright notice
  7.  * and this permission notice appear in supporting documentation, and that
  8.  * the name of Silicon Graphics, Inc. not be used in advertising
  9.  * or publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.
  11.  *
  12.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  13.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  14.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  15.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  16.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  17.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  18.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  19.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  20.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  21.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  22.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  23.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  *
  25.  * US Government Users Restricted Rights
  26.  * Use, duplication, or disclosure by the Government is subject to
  27.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  28.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  29.  * clause at DFARS 252.227-7013 and/or in similar or successor
  30.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  31.  * Unpublished-- rights reserved under the copyright laws of the
  32.  * United States.  Contractor/manufacturer is Silicon Graphics,
  33.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  34.  *
  35.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  36.  */
  37. #include "oglwindow.h"
  38. #include "unitsquare.h"
  39. #include "texture.h"
  40.  
  41. #include <X11/keysym.h>
  42.  
  43. #include <sys/time.h>
  44. #include <malloc.h>
  45. #include <math.h>
  46. #include <stdlib.h>
  47.  
  48. #define FADE_RED    0.0
  49. #define FADE_GREEN    0.0
  50. #define FADE_BLUE    0.0
  51.  
  52. static char def_image0[] = 
  53.   DATADIR "opengl1.128.rgb";
  54. static char def_image1[] = 
  55.   DATADIR "opengl1.128.rgb";
  56. static char def_image2[] = 
  57.   DATADIR "re_coke.rgb";
  58. static char *def_images[3];
  59.  
  60. static float fov = 40.0;
  61. static float zdist = 5.0;        // Distance eye -> origin 
  62.  
  63. static int frame = 0;            // Have square fill entire fov?
  64. static int fix_size = 0;        // Fix size of window to size
  65.                       // of first image?
  66.  
  67. static int rainbow = 0;            // Use rainbow colors for mipmaps?
  68.  
  69. static int fade = 0;            // Fill smaller mipmaps with
  70.                      // black?
  71.  
  72.  
  73. static int use_texture = 1;        // Use textures at all?
  74.  
  75. static float rotx = 0.0, roty = 0.0;    // Rotations about x and y per second
  76.  
  77. const float mouse_poll = 100000;        // How often to poll mouse
  78.  
  79. static float fadecolors[][3] = {
  80.   {1, 0, 0},
  81.   {1, 1, 0},
  82.   {0, 1, 0},
  83.   {0, 1, 1},
  84.   {0, 0, 1},
  85.   {1, 0, 1}};
  86. static int n_colors = 6;
  87.  
  88. static int paused = 0;
  89.  
  90. GLfloat matrix[16];
  91.  
  92. int n_textures;
  93.  
  94. oglwindow *window;
  95. unitsquare *square;
  96.  
  97. int win_height, win_width;
  98.  
  99. int image = 0;
  100.  
  101. /* Note - odd number display lists are the images; the even number that
  102.  * directly follows is the fade for that image */
  103.  
  104. inline float radians(float degrees)
  105. {
  106.   return ((degrees / 180.0) * M_PI);
  107. }
  108.  
  109. inline unsigned long current_time()
  110. {
  111.   struct timeval time;
  112.   gettimeofday(&time, NULL);
  113.   return (time.tv_sec * 1000000 + time.tv_usec);
  114. }
  115.  
  116. inline float transform_z(float *m) 
  117. {
  118.   return (m[10] + m[11]);
  119. }
  120.  
  121. void do_rotation(unsigned long last_time, unsigned long time)
  122. {
  123.   float elapsed_time;
  124.   float z;
  125.  
  126.   elapsed_time = (time - last_time) / 1000000.0;
  127.  
  128.   z = transform_z(matrix);
  129.  
  130.   glPushMatrix(); 
  131.   glLoadIdentity(); 
  132.   if (!paused) {
  133.     glRotatef(elapsed_time * rotx, 1, 0, 0);
  134.     glRotatef(elapsed_time * roty, 0, 1, 0);
  135.   }
  136.   glMultMatrixf(matrix);
  137.   glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
  138.   glPopMatrix(); 
  139.   glMultMatrixf(matrix);
  140.  
  141.   /* If the square has flipped around so that a different face is 
  142.    * is visible, a different image should be used */
  143.   if (n_textures && z * transform_z(matrix) <= 0.0) 
  144.     image = (image + 1) % n_textures;
  145. }
  146.  
  147. unsigned long draw(unsigned long last_draw)
  148. {
  149.   unsigned long time = current_time();
  150.  
  151.   glMatrixMode(GL_PROJECTION);
  152.   glLoadIdentity();
  153.   gluPerspective (fov, 1.0, 0.01, 20.0); 
  154.  
  155.   glMatrixMode(GL_MODELVIEW);
  156.   glLoadIdentity();
  157.   gluLookAt(0, 0, zdist, 0, 0, 0, 0, 1, 0);
  158.  
  159.   glClear(GL_COLOR_BUFFER_BIT);
  160.  
  161.   glColor4ub(255, 255, 255, 255);
  162.  
  163.   glCallList(image * 2 + 1);
  164.   glCallList(image * 2 + 2);
  165.  
  166.   do_rotation(last_draw, time);
  167.  
  168.   square->draw();
  169.   
  170.   window->swapbuffers();
  171.  
  172.   return time;
  173. }
  174.  
  175. int mouse_motion(int oldmx, int oldmy, unsigned long last_time,
  176.                  int mx, int my, unsigned long time)
  177. {
  178.   float dx, dy, dt;
  179.  
  180.   dt = (time - last_time) / 1000000.0;
  181.  
  182.   // Find the mouse motion vector in screen space
  183.   dx = (float)(mx - oldmx) / (float)win_width;
  184.   dy = (float)(my - oldmy) / (float)win_height;
  185.  
  186.   rotx = dy * 180.0 / dt;
  187.   roty = dx * 180.0 / dt;
  188.  
  189.   if (rotx != 0.0 || roty != 0.0) return 1;
  190.   else return 0;
  191. }
  192.  
  193. void show_usage() 
  194. {
  195.   fprintf(stderr, "Usage:\n");
  196.   fprintf(stderr, "fadeflip [-f<field of view>] [-s<speed>] file1.rgb \
  197. [file2.rgb...]\n");
  198. }
  199.  
  200. void main(int argc, char **argv)
  201. {
  202.   Display *dpy;
  203.   XEvent event;
  204.   char buffer[5];
  205.   int bufsize = 5;
  206.   KeySym key;
  207.   XComposeStatus compose;
  208.   Window root_return, child_return;
  209.   int root_x, root_y;
  210.   unsigned int mask_return;
  211.   Window winid;
  212.  
  213.   int fname;
  214.   int width, height;
  215.   texture *texmap;
  216.   int tex_width;
  217.   unsigned long time, last_mouse_time, last_draw = 0.0;
  218.   int oldmx, oldmy, mx, my;
  219.   int button_down = 0;
  220.   int moving = 0;
  221.   int i, j;
  222.   
  223.   square = new unitsquare();
  224.   square->open();
  225.  
  226.   texmap = new texture();
  227.   texmap->open();
  228.   texmap->set_min_filter(GL_LINEAR_MIPMAP_LINEAR);
  229.   texmap->set_environment(GL_DECAL);
  230.  
  231.   fname = argc;
  232.   for (i = 1; i < argc; i++) {
  233.     if (argv[i][0] != '-') {
  234.       fname = i;
  235.       break;
  236.     }
  237.     switch(argv[i][1]) {
  238.     case 'd':                // Fade
  239.       fade = atoi(&argv[i][2]);
  240.       break;
  241.     case 'f':                // Frame
  242.       frame = 1;
  243.       break;
  244.     case 'r':
  245.       rainbow = 1;
  246.       break;
  247.     case 't':                // Use textures?
  248.       use_texture = atoi(&argv[i][2]);
  249.       break;
  250.     case 'v':                // Field of view
  251.       fov = atof(&argv[i][2]);
  252.       break;
  253.     case 'x':
  254.       fix_size = 1;
  255.       break;
  256.     case 'h':
  257.     default:
  258.       show_usage();
  259.       exit(1);
  260.       break;
  261.     }
  262.   }
  263.  
  264.   window = new oglwindow();
  265.   window->set_doublebuffer(1);
  266.   window->set_title("fadeflip");
  267.  
  268.   if (use_texture) {
  269.     n_textures = argc - fname;
  270.     if (n_textures == 0) {
  271.       n_textures = 3;
  272.       argc = 3;
  273.       fname = 0;
  274.       def_images[0] = def_image0;
  275.       def_images[1] = def_image1;
  276.       def_images[2] = def_image2;
  277.       argv = def_images;
  278.     }
  279.  
  280.     texmap->create_from_file(argv[fname]);
  281.     
  282.     if (fix_size) {
  283.       width = texmap->get_width();
  284.       height = texmap->get_height();
  285.       window->set_minsize(width, height);
  286.       window->set_maxsize(width, height);
  287.     } 
  288.   } else n_textures = 0;
  289.  
  290.   window->add_event_mask(ButtonReleaseMask);
  291.   window->open();
  292.   window->map();
  293.   window->winset();
  294.   glClear(GL_COLOR_BUFFER_BIT);
  295.  
  296.   dpy = window->get_display();
  297.   win_width = window->get_width();
  298.   win_height = window->get_height();
  299.   winid = window->get_window();
  300.  
  301.   /* Tex_width = size of unit square in pixels at given distance when 
  302.    * parallel to viewing plane */
  303.   tex_width = (int)((float)window->get_width() / 
  304.             (zdist * tan(radians(fov / 2.0))));
  305.  
  306.   for (i = 0; i < n_textures; i++) {
  307.     texmap->create_from_file(argv[fname++]);
  308.  
  309.     glNewList(i*2 + 1, GL_COMPILE);
  310.     texmap->specify_texture();
  311.     glEndList();
  312.  
  313.     glNewList(i*2 + 2, GL_COMPILE);
  314.     if (fade) {
  315.       width = texmap->get_width();
  316.       height = texmap->get_height();
  317.       height = width < height ? width : height;
  318.       for (width = 1; width < height; width *= 2);
  319.       j = 1;
  320.       width /= 2;
  321.       while (width >= tex_width) {
  322.     width /= 2;
  323.     j++;
  324.       }
  325.       while (1) {
  326.     if (rainbow) 
  327.       texmap->create_color(width, fadecolors[j%n_colors][0],
  328.                    fadecolors[j%n_colors][1], 
  329.                    fadecolors[j%n_colors][2], 1, 1);
  330.     else texmap->create_color(width, 0, 0, 0, 1, 1);
  331.     texmap->set_level(j++);
  332.     texmap->setup_texture();
  333.     texmap->specify_mipmap();
  334.     if (width == 1) break;
  335.     width /= 2;
  336.       }
  337.     }
  338.     glEndList();
  339.     texmap->pixels_free();
  340.   }
  341.  
  342.   if (frame) zdist = 1.0 / tan(radians(fov) / 2.0);    
  343.  
  344.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  345.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  346.   if (use_texture) glEnable(GL_TEXTURE_2D); 
  347.  
  348.   glMatrixMode(GL_MODELVIEW);
  349.   glLoadIdentity();
  350.   glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
  351.   
  352.   while (1) {
  353.     while(((moving || button_down) && XPending(dpy)) ||
  354.     (moving == 0 && button_down == 0)) {
  355.       XNextEvent(dpy, &event);
  356.       switch(event.type) {
  357.       case Expose:
  358.         last_draw = draw(last_draw);
  359.         break;
  360.       case ConfigureNotify:
  361.         window->resize();
  362.     win_width = window->get_width();
  363.     win_height = window->get_height();
  364.         break;
  365.       case ButtonPress:
  366.     button_down = 1;
  367.     oldmx = event.xbutton.x;
  368.     oldmy = event.xbutton.y;
  369.     last_mouse_time = current_time();
  370.     break;
  371.       case ButtonRelease:
  372.     button_down = 0;
  373.     break;
  374.       case KeyPress:
  375.         XLookupString(&event.xkey, buffer, bufsize, &key, &compose);
  376.         if (key == XK_Escape) exit(0);
  377.             else if (key == XK_h || key == XK_H) {
  378.           rotx = roty = 0.0;
  379.           moving = 0;
  380.       paused = 0;
  381.           last_draw = draw(last_draw);
  382.         }
  383.         else if (key == XK_w || key == XK_W) {
  384.           rotx = roty = 0.0;
  385.           glPushMatrix();
  386.           glLoadIdentity();
  387.           glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
  388.           glPopMatrix();
  389.           moving = 0;
  390.       paused = 0;
  391.           last_draw = draw(last_draw);
  392.         }
  393.     else if (key == XK_space) paused = ~paused;
  394.     break;
  395.       }
  396.     }
  397.     if (moving) time = last_draw = draw(last_draw);
  398.     else time = current_time();
  399.     if (button_down && time - last_mouse_time > mouse_poll) {
  400.       XQueryPointer(dpy, winid, &root_return, &child_return, &root_x,
  401.                     &root_y, &mx, &my, &mask_return);
  402.       moving = mouse_motion(oldmx, oldmy, last_mouse_time, mx, my, time);
  403.       oldmx = mx;
  404.       oldmy = my;
  405.       last_mouse_time = time;
  406.     }
  407.   }
  408.  
  409. }
  410.  
  411.